home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / misc / gc103 / gc103.c < prev    next >
C/C++ Source or Header  |  1990-01-03  |  5KB  |  193 lines

  1. /*
  2.  *      gc.c
  3.  *
  4.  *      Great Circle.  This program is used to determine bearing
  5.  *      and range to a station given latitude and longitude.
  6.  *
  7.  *      Ver 1.03 By S. R. Sampson, N5OWK
  8.  *      Public Domain (p) November 1989
  9.  *
  10.  *      Ref: Air Force Manual 51-40, "Air Navigation", 1 February 1987
  11.  *
  12.  *      Usage examples:
  13.  *
  14.  *      gc 35.19n97.27w 0s0e            (Moore to Prime/Equator)
  15.  *      gc 35.19N97.27W 38.51n77.02W    (Moore to Washington D.C.)
  16.  *      gc 33.56n118.24w 55.45n37.35e   (L.A. to Moscow U.S.S.R.)
  17.  *    gc 35N70W 35N71W        (No decimal points used)
  18.  */
  19.  
  20. /* Includes */
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <math.h>
  26.  
  27. /* Defines */
  28.  
  29. #define RADIAN  (180.0 / M_PI)
  30.  
  31. /* Globals */
  32.  
  33. double  tmp,
  34.         dist,
  35.         range,
  36.         bearing,
  37.         QTH_Lat,
  38.         QTH_Long,
  39.         DEST_Lat,
  40.         DEST_Long,
  41.         Delta_Long;
  42.  
  43. /* Simple Declare, No Prototypes */
  44.  
  45. /*
  46.  *      Error routine
  47.  */
  48.  
  49. void err(type)
  50. int     type;
  51. {
  52.         switch(type)  {
  53.         case 1:
  54.                 printf("\007Latitude Out of Range (90N to 90S)\n");
  55.                 break;
  56.         case 2:
  57.                 printf("\007Longitude Out of Range (180W to 180E)\n");
  58.                 break;
  59.         case 3:
  60.                 printf("\007Minutes Out of Range (0 to 59)\n");
  61.         }
  62.  
  63.         exit(1);
  64. }
  65.  
  66. /*
  67.  *      Convert Degrees and Minutes to Decimal
  68.  */
  69.  
  70. double dm2dec(n)
  71. double  n;
  72. {
  73.         double  t;
  74.  
  75.         t = (int)n;
  76.         n -= t;
  77.         n /= .60;
  78.  
  79.         if (n >= 1.0)
  80.                 err(3);
  81.  
  82.         return (n + t);
  83. }
  84.  
  85. /*
  86.  *      Parse the input line
  87.  *
  88.  *      dd(.mm)[NnSs]ddd(.mm)[EeWw]
  89.  */
  90.  
  91. void parse(s, lat, lon)
  92. char    *s;
  93. double  *lat, *lon;
  94. {
  95.         register char   *i, *t;
  96.         int             l;
  97.  
  98.         l = strlen(s);
  99.         for (i = s; i < (s + l); ++i)  {
  100.                 switch(toupper(*i))  {
  101.                 case 'N':
  102.                         *i = '\0';
  103.                         t = i + 1;
  104.                         *lat = atof(s);
  105.                         break;
  106.                 case 'S':
  107.                         *i = '\0';
  108.                         t = i + 1;
  109.                         *lat = -atof(s);
  110.                         break;
  111.                 case 'E':
  112.                         *i = '\0';
  113.                         *lon = -atof(t);
  114.                         break;
  115.                 case 'W':
  116.                         *i = '\0';
  117.                         *lon = atof(t);
  118.                 }
  119.         }
  120.  
  121.         *lat = dm2dec(*lat);
  122.         *lon = dm2dec(*lon);
  123.  
  124.         if (*lat > 90.0 || *lat < -90.0)
  125.                 err(1);
  126.  
  127.         if (*lon > 180.0 || *lon < -180.0)
  128.                 err(2);
  129.  
  130.         /* Prevent ACOS() Domain Error */
  131.  
  132.         if (*lat == 90.0)
  133.                 *lat = 89.9;
  134.  
  135.         if (*lat == -90.0)
  136.                 *lat = -89.9;
  137. }
  138.  
  139. main(argc, argv)
  140. register int  argc;
  141. register char **argv;
  142. {
  143.         if (argc != 3)  {
  144.                 printf("Usage: gc station1 station2\n\n");
  145.                 printf("This program computes Great Circle Bearing and Range\n");
  146.                 printf("given the latitude and longitude (degrees and minutes).\n\n");
  147.                 printf("You must input the lat/long of the two stations.\n");
  148.                 printf("The output will then be relative from station1 to station2.\n\n");
  149.                 printf("Input the two station lat/longs using the following format:\n\n");
  150.                 printf("\tdd.mmHddd.mmG  lead/lagging zeros can be left out.\n\n");
  151.                 printf("d = Degrees, m = Minutes, H = Hemisphere (N or S), G = Greenwich (W or E)\n");
  152.  
  153.                 exit(1);
  154.         }
  155.  
  156.         /* Process the command line data */
  157.  
  158.         parse(argv[1], &QTH_Lat, &QTH_Long);
  159.         parse(argv[2], &DEST_Lat, &DEST_Long);
  160.  
  161.         /* Compute the Bearing and Range, From the Formula in Chapter 23 */
  162.  
  163.         Delta_Long = DEST_Long - QTH_Long;
  164.  
  165.         QTH_Lat    /= RADIAN;   /* Convert variables to Radians */
  166.         QTH_Long   /= RADIAN;
  167.         DEST_Lat   /= RADIAN;
  168.         Delta_Long /= RADIAN;
  169.  
  170.         tmp = (sin(QTH_Lat) * sin(DEST_Lat)) +
  171.                 (cos(QTH_Lat) * cos(DEST_Lat) * cos(Delta_Long));
  172.  
  173.         dist = acos(tmp);
  174.         range = 60.0 * (dist * RADIAN);
  175.  
  176.         tmp = (sin(DEST_Lat) - (sin(QTH_Lat) * cos(dist))) /
  177.                 (sin(dist) * cos(QTH_Lat));
  178.  
  179.         bearing = acos(tmp) * RADIAN;
  180.  
  181.         if (Delta_Long > 0.0)
  182.                 bearing = 360.0 - bearing;
  183.  
  184.         /* Computations complete, show answer */
  185.  
  186.         printf("\nBearing is %.0f Degrees for %.0f Nautical Miles\n",
  187.                 bearing, range);
  188.  
  189.         exit(0);
  190. }
  191.  
  192. /* EOF */
  193.